library(tidyverse)
library(scales)
library(plotly)
library(lubridate)

Beds

beds <- read_csv("raw_data/non_covid_raw_data/beds_by_nhs_board_of_treatment_and_specialty.csv") %>% janitor::clean_names()
beds %>% 
  filter(specialty_name == "All Acute") %>% 
  ggplot(aes(x = quarter, y = percentage_occupancy))+
  geom_line(aes(colour = hb), group = 1)+
  facet_wrap(~ hb)

beds <- beds %>% 
  select(-c(2,4,6,8,10,12,14,16,18,20)) %>% 
  filter(!hb %in% c("SB0801", "S92000003"))

beds <- beds %>% 
  filter(!hb %in% c("SB0801", "S92000003")) %>% 
  filter(hb == location)
  
# beds %>% 
# count(specialty_name)

a_e_beds <- beds %>% 
  filter(specialty_name == "Accident & Emergency")
#all time bed occupancy percentage for health boards
a_e_beds %>% 
  group_by(quarter, hb) %>% 
  summarise(mean_perc_occ = mean(percentage_occupancy, na.rm = TRUE)) %>% 
ungroup() %>% 
  group_by(hb) %>% 
  summarise(avg_per_occ_all_time = mean(mean_perc_occ)) %>% 
  arrange(desc(avg_per_occ_all_time)) %>% 
  ggplot(aes(x = hb, y = avg_per_occ_all_time))+
  geom_col()+
  geom_point()+
  theme(axis.text.x = element_text(angle = 45))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# workout the ten largest 
ten_largest_specialities <- beds %>%
  group_by(specialty_name) %>% 
  summarise(mean_avail_staffed_beds = mean(average_available_staffed_beds)) %>% 
  arrange(desc(mean_avail_staffed_beds)) %>% 
  slice_max(mean_avail_staffed_beds, n=10) %>% 
  select(1) %>% 
  pull()



# bed percentage availablity for top ten largest specialities
beds %>%
  filter(specialty_name %in% ten_largest_specialities) %>% 
  group_by(quarter, specialty_name) %>%
  summarise(mean_perc_occ = mean(percentage_occupancy)) %>% 
  ggplot(aes(x = quarter, y = mean_perc_occ))+
  geom_line(aes(colour = specialty_name, group = specialty_name))+
  geom_point()+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

  
# bed percentage availablity for all acute
  beds %>%
  filter(specialty_name == "All Acute") %>% 
  group_by(quarter, specialty_name) %>%
  summarise(mean_perc_occ = mean(percentage_occupancy)) %>% 
  ggplot(aes(x = quarter, y = mean_perc_occ))+
  geom_line(aes(colour = specialty_name, group = specialty_name))+
  geom_point()+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

  
  # bed percentage availability for intensive care
beds %>%
  filter(specialty_name == "Intensive Care Medicine") %>% 
  group_by(quarter, specialty_name) %>%
  summarise(mean_perc_occ = mean(percentage_occupancy)) %>% 
  ggplot(aes(x = quarter, y = mean_perc_occ))+
  geom_line(aes(colour = specialty_name, group = specialty_name))+
  geom_point()+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

NA
NA
NA
a_e_beds %>% 
  group_by(quarter) %>% 
  summarise(mean_available_beds = mean(average_available_staffed_beds, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = mean_available_beds))+
  geom_line(group ="1")+
  geom_point()+
  theme(axis.text.x = element_text(angle = 45))


age_sex <- read_csv("raw_data/non_covid_raw_data/inpatient_and_daycase_by_nhs_board_of_treatment_age_and_sex.csv") %>% janitor::clean_names()
Rows: 129393 Columns: 18── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (12): Quarter, QuarterQF, HB, HBQF, Location, LocationQF, AdmissionType, AdmissionTypeQF, Sex, Age, AverageLengthOfEpisodeQF, Aver...
dbl  (6): Episodes, LengthOfEpisode, AverageLengthOfEpisode, Stays, LengthOfStay, AverageLengthOfStay
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
health_board_names <- read_csv("raw_data/non_covid_raw_data/health_board_names.csv")
Rows: 18 Columns: 5── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (3): HB, HBName, Country
dbl (2): HBDateEnacted, HBDateArchived
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
age_sex %>% 
  count(hb)

season_age_sex <- age_sex %>% 
  mutate(date = yq(quarter),
         year = year(date),
         month = month(date, label = TRUE, abbr = FALSE),
         season = case_when(
           str_detect(month, "December") ~ "Winter",
           str_detect(month, "January") ~ "Winter",
           str_detect(month, "February") ~ "Winter",
           str_detect(month, "March") ~ "Spring",
           str_detect(month, "April") ~ "Spring",
           str_detect(month, "May") ~ "Spring",
           str_detect(month, "June") ~ "Summer",
           str_detect(month, "July") ~ "Summer",
           str_detect(month, "August") ~ "Summer",
           str_detect(month, "September") ~ "Autumn",
           str_detect(month, "October") ~ "Autumn",
           str_detect(month, "November") ~ "Autumn"),
         season = factor(season, order = TRUE)) 

library(lubridate)
library(zoo)

Attaching package: ‘zoo’

The following objects are masked from ‘package:base’:

    as.Date, as.Date.numeric
# change quarter column into the date at the start of each quarter
 age_sex <-  age_sex %>% 
    mutate(quarter = yq(quarter))

 # shows the total length of stay by age bracket for emergency inpatients
age_sex %>% 
  filter(admission_type == "Emergency Inpatients") %>% 
  group_by(quarter, age) %>% 
  summarise(total_length_of_stay = sum(length_of_stay)) %>% 
  ggplot(aes(x = quarter, y = total_length_of_stay))+
  geom_line(aes(colour = age))+
  theme(axis.text.x = element_text(angle = 45))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

age_sex %>% 
count(admission_type)

age_sex
 # shows the total length of stay by age bracket for elective inpatients
age_sex %>% 
  filter(admission_type == "Elective Inpatients") %>% 
  group_by(quarter, age) %>% 
  summarise(total_length_of_stay = sum(length_of_stay)) %>% 
  ggplot(aes(x = quarter, y = total_length_of_stay))+
  geom_line(aes(colour = age))+
  theme(axis.text.x = element_text(angle = 45))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

 # shows the mean length of stay by age bracket for elective inpatients
# can facet by sex 
age_sex %>% 
  filter(admission_type == "Elective Inpatients") %>% 
  group_by(quarter, age) %>% 
  summarise(avg_length_of_stay = mean(average_length_of_stay, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = avg_length_of_stay))+
  geom_line(aes(colour = age, group = age))+
  theme(axis.text.x = element_text(angle = 45))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

age_sex %>% 
  mutate(date = yq(quarter),
         year = year(date),
         month = month(date, label = TRUE, abbr = FALSE),
         season = case_when(
           str_detect(month, "December") ~ "Winter",
           str_detect(month, "January") ~ "Winter",
           str_detect(month, "February") ~ "Winter",
           str_detect(month, "March") ~ "Spring",
           str_detect(month, "April") ~ "Spring",
           str_detect(month, "May") ~ "Spring",
           str_detect(month, "June") ~ "Summer",
           str_detect(month, "July") ~ "Summer",
           str_detect(month, "August") ~ "Summer",
           str_detect(month, "September") ~ "Autumn",
           str_detect(month, "October") ~ "Autumn",
           str_detect(month, "November") ~ "Autumn"),
         season = factor(season, order = TRUE)) 
Warning: All formats failed to parse. No formats found.

age_sex %>% 
  filter(admission_type == "Emergency Inpatients") %>% 
  group_by(quarter, sex) %>% 
  summarise(avg_length_of_stay = mean(average_length_of_stay, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = avg_length_of_stay))+
  geom_line(aes(colour = sex, group = sex))+
  theme(axis.text.x = element_text(angle = 45))+
  geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
  geom_point(aes(colour = sex), size = 0.5)+
  labs(title = "Emergency Inpatient by gender and average length of stay")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

age_sex %>% 
  filter(admission_type == "Elective Inpatients") %>% 
  group_by(quarter, sex) %>% 
  summarise(avg_length_of_stay = mean(average_length_of_stay, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = avg_length_of_stay))+
  geom_line(aes(colour = sex, group = sex))+
  theme(axis.text.x = element_text(angle = 45))+
  geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
  geom_point(aes(colour = sex), size = 0.5)+
  labs(title = "Elective Inpatient by gender and average length of stay")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# emergency inpatient by age and avg length of stay
age_sex %>% 
  filter(admission_type == "Emergency Inpatients") %>% 
  group_by(quarter, age) %>% 
  summarise(avg_length_of_stay = mean(average_length_of_stay, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = avg_length_of_stay))+
  geom_line(aes(colour = age, group = age))+
  theme(axis.text.x = element_text(angle = 45))+
  #geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
  geom_point(aes(colour = age), size = 0.5)+
  labs(title = "Emergency inpatient by age and avg length of stay")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# elective inpatient by age and avg length of stay
age_sex %>% 
  filter(admission_type == "Elective Inpatients") %>% 
  group_by(quarter, age) %>% 
  summarise(avg_length_of_stay = mean(average_length_of_stay, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = avg_length_of_stay))+
  geom_line(aes(colour = age, group = age))+
  theme(axis.text.x = element_text(angle = 45))+
  #geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
  geom_point(aes(colour = age), size = 0.5)+
  labs(title = "Elective inpatient by age and avg length of stay")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# emergency inpatient by age and avg episodes
age_sex %>% 
  filter(admission_type == "Emergency Inpatients") %>% 
  group_by(quarter, age) %>% 
  summarise(avg_episodes = mean(episodes, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = avg_episodes))+
  geom_line(aes(colour = age, group = age))+
  theme(axis.text.x = element_text(angle = 45))+
  #geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
  geom_point(aes(colour = age), size = 0.5)+
  labs(title = "Emergency inpatient by age and avg episodes")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# emergency inpatient by age and avg episodes
age_sex %>% 
  filter(admission_type == "Elective Inpatients") %>% 
  group_by(quarter, age) %>% 
  summarise(avg_episodes = mean(episodes, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = avg_episodes))+
  geom_line(aes(colour = age, group = age))+
  theme(axis.text.x = element_text(angle = 45))+
  #geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
  geom_point(aes(colour = age), size = 0.5)+
  labs(title = "Emergency inpatient by age and avg episodes")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# Plot comparison of Emergency vs Elective submissions
age_sex %>% 
  filter(admission_type %in% c("Emergency Inpatients", "Elective Inpatients")) %>% 
  group_by(quarter, admission_type) %>% 
  summarise(avg_stay = mean(average_length_of_stay, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = avg_stay, colour = admission_type))+
  geom_line(aes(group = admission_type))+
  geom_point()+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# avg_stay by admission type
age_sex %>% 
  group_by(quarter, admission_type) %>% 
  summarise(avg_stay = mean(average_length_of_stay, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = avg_stay, colour = admission_type))+
  geom_line(aes(group = admission_type))+
  geom_point()+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# avg_stay for all types
age_sex %>% 
  group_by(quarter) %>% 
  summarise(avg_stay = mean(average_length_of_stay, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = avg_stay, group = 1))+
  geom_line(aes(group = 1))+
  geom_point()+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))


# number of stays for all types
age_sex %>% 
  group_by(quarter) %>% 
  summarise(total_stays = sum(stays, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = total_stays, group = 1))+
  geom_line(aes(group = 1))+
  geom_point()+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

simd <- read_csv("raw_data/non_covid_raw_data/inpatient_and_daycase_by_nhs_board_of_treatment_and_simd.csv") %>% janitor::clean_names()
Rows: 40821 Columns: 18── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (11): Quarter, QuarterQF, HB, HBQF, Location, LocationQF, AdmissionType, AdmissionTypeQF, SIMDQF, AverageLengthOfEpisodeQF, Averag...
dbl  (7): SIMD, Episodes, LengthOfEpisode, AverageLengthOfEpisode, Stays, LengthOfStay, AverageLengthOfStay
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#total episodes(hospitalisations?) by simd value
simd %>% 
  drop_na(simd) %>%
  mutate(simd = as.factor(simd)) %>% # gives each simd a separate colour
  group_by(quarter, simd) %>% 
  summarise(total_episodes = sum(episodes, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = total_episodes, group = simd))+
  geom_line(aes(colour = simd))+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))+
  scale_y_continuous(labels = scales::comma)
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

  
#avg episodes(hospitalisations?) by simd value
simd %>% 
  drop_na(simd) %>%
  mutate(simd = as.factor(simd)) %>% # gives each simd a separate colour
  group_by(quarter, simd) %>% 
  summarise(avg_episodes = mean(average_length_of_episode, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = avg_episodes, group = simd))+
  geom_line(aes(colour = simd))+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))+
  scale_y_continuous(labels = scales::comma)
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

NA
# plot avg stay length for most and least deprived for emergency unpatients
simd %>% 
  filter(admission_type == "Emergency Inpatients", simd %in% c(1,5)) %>% 
  drop_na(simd) %>% 
  group_by(quarter,simd) %>% 
  summarise(avg_stay_length = mean(average_length_of_stay, na.rm = TRUE)) %>% 
  ggplot(aes(x = quarter, y = avg_stay_length)) +
  geom_line(aes(colour = simd, group = simd))+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

NA
speciality <- read_csv("raw_data/non_covid_raw_data/inpatient_and_daycase_by_nhs_board_of_treatment_and_specialty.csv") %>% janitor::clean_names()
Rows: 95270 Columns: 18── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (12): Quarter, QuarterQF, HB, HBQF, Location, LocationQF, AdmissionType, AdmissionTypeQF, Specialty, SpecialtyName, AverageLengthO...
dbl  (6): Episodes, LengthOfEpisode, AverageLengthOfEpisode, Spells, LengthOfSpell, AverageLengthOfSpell
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
ae_wait_times <- read_csv("raw_data/non_covid_raw_data/monthly_ae_waitingtimes_202206.csv") %>% janitor::clean_names()
Rows: 15837 Columns: 25── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (13): Country, HBT, TreatmentLocation, DepartmentType, NumberOfAttendancesEpisodeQF, NumberMeetingTargetEpisodeQF, DischargeDestin...
dbl (12): Month, NumberOfAttendancesAggregate, NumberOfAttendancesEpisode, NumberMeetingTargetAggregate, NumberMeetingTargetEpisode, D...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#glimpse(ae_wait_times)


#make a date and year column with the first date of every month
ae_wait_times <- ae_wait_times %>% 
  mutate(date = ym(month), .after = month,
         year = year(date))

#make a percent column with percent of patients meeting the 4hr target time
ae_wait_times <- ae_wait_times %>% 
  mutate(percent_4hr_target_achieved = (number_meeting_target_aggregate/number_of_attendances_aggregate)*100) %>% 
  #add an 8hr one - not currently used
mutate(percent_seen_within_8hr = ((number_of_attendances_aggregate-attendance_greater8hrs)/number_of_attendances_aggregate)*100)
# draw percentage of 4 hour wait for all years
for_plotly <- ae_wait_times %>% 
  filter(department_type == "Emergency Department") %>% 
  group_by(date, department_type) %>% 
  summarise(avg_4hr_target_made = mean(percent_4hr_target_achieved)) %>% 
  ggplot(aes(x = date, y = avg_4hr_target_made))+
  geom_line(aes(colour = department_type))+
  scale_x_date(date_breaks = "6 months", date_labels =  "%b %Y")+
  theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7))+
  geom_smooth()+
  geom_vline(xintercept = as.numeric(as.Date("2008-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2009-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2010-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2011-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2012-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2013-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2014-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2015-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2016-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2017-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2018-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2019-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2020-01-01")), linetype=4)+
  labs(title = "percentage of A&E departments meeting the 4 hr target turnaround for patients",
       subtitle = "added in vertical lines for January to help")
`summarise()` has grouped output by 'date'. You can override using the `.groups` argument.
ggplotly(for_plotly)
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
Warning: `gather_()` was deprecated in tidyr 1.2.0.
Please use `gather()` instead.
# 4hr wait by health board for all years facet wrapped
ae_wait_times %>% 
  filter(department_type == "Emergency Department") %>% 
  group_by(date, hbt) %>% 
  mutate(avg_4hr_target_made = mean(percent_4hr_target_achieved)) %>% 
  slice(1) %>%  
  ggplot(aes(x = date, y = avg_4hr_target_made))+
  geom_line(aes(colour = hbt))+
  scale_x_date(date_breaks = "6 months", date_labels =  "%b %Y")+
  theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7))+
  geom_smooth()+
  geom_vline(xintercept = as.numeric(as.Date("2008-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2009-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2010-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2011-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2012-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2013-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2014-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2015-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2016-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2017-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2018-01-01")), linetype=4)+
  geom_vline(xintercept = as.numeric(as.Date("2019-01-01")), linetype=4)+
  facet_wrap(~ hbt)

target_2007 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>% 
  filter(year == 2007) %>% 
  rename(ae_target_2007 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  select(hbt,ae_target_2007)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
target_2018 <- ae_wait_times %>%
  group_by(year, hbt) %>% 
  summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>% 
  filter(year == 2018) %>% 
  rename(ae_target_2018 = ae_4hr_target_achieved) %>% 
  ungroup() %>% 
  select(hbt,ae_target_2018)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
library(sf)
Linking to GEOS 3.9.1, GDAL 3.4.3, PROJ 7.2.1; sf_use_s2() is TRUE
scotland <- st_read("../SG_NHS_HealthBoards_2019_shapefile/SG_NHS_HealthBoards_2019.shp")
Reading layer `SG_NHS_HealthBoards_2019' from data source 
  `C:\Users\neilp\Documents\CODECLAN\phs_scotland_group_project\SG_NHS_HealthBoards_2019_shapefile\SG_NHS_HealthBoards_2019.shp' 
  using driver `ESRI Shapefile'
Simple feature collection with 14 features and 4 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 5512.998 ymin: 530250.8 xmax: 470332 ymax: 1220302
Projected CRS: OSGB 1936 / British National Grid
# view(scotland)
# 
head(scotland, 3)
Simple feature collection with 3 features and 4 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 186130 ymin: 530250.8 xmax: 398017.2 ymax: 672679.8
Projected CRS: OSGB 1936 / British National Grid
     HBCode                HBName Shape_Leng Shape_Area                       geometry
1 S08000015    Ayrshire and Arran   679782.3 3408802229 MULTIPOLYGON (((201916.2 60...
2 S08000016               Borders   525406.7 4742684960 MULTIPOLYGON (((345325.9 57...
3 S08000017 Dumfries and Galloway   830301.2 6676314851 MULTIPOLYGON (((266004.4 54...
# 
plot(scotland[-1])


scotland <-  scotland %>% 
  mutate(centres = st_centroid(st_make_valid(geometry))) %>%
    mutate(lat = st_coordinates(centres)[,1],
           long = st_coordinates(centres)[,2],
           target_2007 = target_2007$ae_target_2007,
           target_2018 = target_2018$ae_target_2018,
           change_ae = target_2007 - target_2018)

ggplot(data = scotland) +
    geom_sf(aes(fill = change_ae)) +
    scale_fill_viridis_c(option = "plasma")+
  labs(title = "percent change in A&E depts meeting the 4 hour target 2007 - 2018")

  

ggplot(data = scotland) +
    geom_sf(aes(fill = target_2018)) +
    scale_fill_viridis_c(option = "plasma")+
  labs(title = "Percent of A&E depts making the 4hr target")

ggplot(data = scotland) +
geom_sf(fill = "green")+
ggrepel::geom_text_repel(aes(x = lat , y = long, label = paste(HBCode, HBName, sep = "\n")), min.segment.length = 0.05,size = 3, color = "black", fontface = "bold") +
  theme_void()


library(sf)

scotland_smaller <- scotland %>% # make a smaller version for performance issues
  st_simplify(TRUE, dTolerance = 2000)
#fixes problems caused by above 
scotland_smaller <- sf::st_cast(scotland_smaller, "MULTIPOLYGON")


# 
#   fig <- ggplotly(
#     ggplot(scotland)+
#   geom_sf(aes(fill = HBName))
# )
#   fig

  
  p <- ggplot(scotland_smaller) + 
  geom_sf(aes(fill = HBName, text = paste("<b>", HBName, "</b>\n", HBCode)))+
    theme_void()
Warning: Ignoring unknown aesthetics: text
  p %>%
  ggplotly(tooltip = "text") %>%
  style(hoverlabel = list(bgcolor = "white"), hoveron = "fill")
NA
NA
covid_age_sex <- read_csv("raw_data/covid_raw_data/hospital_admissions_hb_agesex_20220302.csv")
Rows: 43516 Columns: 12── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (8): HB, HBQF, AgeGroup, AgeGroupQF, Sex, SexQF, AdmissionType, AdmissionTypeQF
dbl (4): WeekEnding, NumberAdmissions, Average20182019, PercentVariation
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(covid_age_sex)
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoc2NhbGVzKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmBgYA0KIyBCZWRzDQpgYGB7cn0NCmJlZHMgPC0gcmVhZF9jc3YoInJhd19kYXRhL25vbl9jb3ZpZF9yYXdfZGF0YS9iZWRzX2J5X25oc19ib2FyZF9vZl90cmVhdG1lbnRfYW5kX3NwZWNpYWx0eS5jc3YiKSAlPiUgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKQ0KYGBgDQoNCmBgYHtyfQ0KYmVkcyAlPiUgDQogIGZpbHRlcihzcGVjaWFsdHlfbmFtZSA9PSAiQWxsIEFjdXRlIikgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gcGVyY2VudGFnZV9vY2N1cGFuY3kpKSsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBoYiksIGdyb3VwID0gMSkrDQogIGZhY2V0X3dyYXAofiBoYikNCmBgYA0KDQpgYGB7cn0NCmJlZHMgPC0gYmVkcyAlPiUgDQogIHNlbGVjdCgtYygyLDQsNiw4LDEwLDEyLDE0LDE2LDE4LDIwKSkgJT4lIA0KICBmaWx0ZXIoIWhiICVpbiUgYygiU0IwODAxIiwgIlM5MjAwMDAwMyIpKQ0KDQpiZWRzIDwtIGJlZHMgJT4lIA0KICBmaWx0ZXIoIWhiICVpbiUgYygiU0IwODAxIiwgIlM5MjAwMDAwMyIpKSAlPiUgDQogIGZpbHRlcihoYiA9PSBsb2NhdGlvbikNCiAgDQojIGJlZHMgJT4lIA0KIyBjb3VudChzcGVjaWFsdHlfbmFtZSkNCg0KYV9lX2JlZHMgPC0gYmVkcyAlPiUgDQogIGZpbHRlcihzcGVjaWFsdHlfbmFtZSA9PSAiQWNjaWRlbnQgJiBFbWVyZ2VuY3kiKQ0KYGBgDQoNCmBgYHtyfQ0KIyBhJmUgcGVyY2VudGFnZSBvY2N1cGFuY3kgYnkgaGIgb3ZlciB0aW1lDQphX2VfYmVkcyAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIGhiKSAlPiUgDQogIHN1bW1hcmlzZShtZWFuX3BlcmNfb2NjID0gbWVhbihwZXJjZW50YWdlX29jY3VwYW5jeSwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gbWVhbl9wZXJjX29jYykpKw0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gaGIsIGNvbG91ciA9IGhiKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSkpDQoNCg0KYV9lX2JlZHMgJT4lIA0KICBjb3VudChoYikNCmBgYA0KDQpgYGB7cn0NCiNhbGwgdGltZSBiZWQgb2NjdXBhbmN5IHBlcmNlbnRhZ2UgZm9yIGhlYWx0aCBib2FyZHMNCmFfZV9iZWRzICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgaGIpICU+JSANCiAgc3VtbWFyaXNlKG1lYW5fcGVyY19vY2MgPSBtZWFuKHBlcmNlbnRhZ2Vfb2NjdXBhbmN5LCBuYS5ybSA9IFRSVUUpKSAlPiUgDQp1bmdyb3VwKCkgJT4lIA0KICBncm91cF9ieShoYikgJT4lIA0KICBzdW1tYXJpc2UoYXZnX3Blcl9vY2NfYWxsX3RpbWUgPSBtZWFuKG1lYW5fcGVyY19vY2MpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhhdmdfcGVyX29jY19hbGxfdGltZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gaGIsIHkgPSBhdmdfcGVyX29jY19hbGxfdGltZSkpKw0KICBnZW9tX2NvbCgpKw0KICBnZW9tX3BvaW50KCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKQ0KDQpgYGANCg0KDQpgYGB7cn0NCiMgd29ya291dCB0aGUgdGVuIGxhcmdlc3QgDQp0ZW5fbGFyZ2VzdF9zcGVjaWFsaXRpZXMgPC0gYmVkcyAlPiUNCiAgZ3JvdXBfYnkoc3BlY2lhbHR5X25hbWUpICU+JSANCiAgc3VtbWFyaXNlKG1lYW5fYXZhaWxfc3RhZmZlZF9iZWRzID0gbWVhbihhdmVyYWdlX2F2YWlsYWJsZV9zdGFmZmVkX2JlZHMpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhtZWFuX2F2YWlsX3N0YWZmZWRfYmVkcykpICU+JSANCiAgc2xpY2VfbWF4KG1lYW5fYXZhaWxfc3RhZmZlZF9iZWRzLCBuPTEwKSAlPiUgDQogIHNlbGVjdCgxKSAlPiUgDQogIHB1bGwoKQ0KDQoNCg0KIyBiZWQgcGVyY2VudGFnZSBhdmFpbGFibGl0eSBmb3IgdG9wIHRlbiBsYXJnZXN0IHNwZWNpYWxpdGllcw0KYmVkcyAlPiUNCiAgZmlsdGVyKHNwZWNpYWx0eV9uYW1lICVpbiUgdGVuX2xhcmdlc3Rfc3BlY2lhbGl0aWVzKSAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIHNwZWNpYWx0eV9uYW1lKSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fcGVyY19vY2MgPSBtZWFuKHBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gbWVhbl9wZXJjX29jYykpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IHNwZWNpYWx0eV9uYW1lLCBncm91cCA9IHNwZWNpYWx0eV9uYW1lKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCiAgDQojIGJlZCBwZXJjZW50YWdlIGF2YWlsYWJsaXR5IGZvciBhbGwgYWN1dGUNCiAgYmVkcyAlPiUNCiAgZmlsdGVyKHNwZWNpYWx0eV9uYW1lID09ICJBbGwgQWN1dGUiKSAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIHNwZWNpYWx0eV9uYW1lKSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fcGVyY19vY2MgPSBtZWFuKHBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gbWVhbl9wZXJjX29jYykpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IHNwZWNpYWx0eV9uYW1lLCBncm91cCA9IHNwZWNpYWx0eV9uYW1lKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCiAgDQogICMgYmVkIHBlcmNlbnRhZ2UgYXZhaWxhYmlsaXR5IGZvciBpbnRlbnNpdmUgY2FyZQ0KYmVkcyAlPiUNCiAgZmlsdGVyKHNwZWNpYWx0eV9uYW1lID09ICJJbnRlbnNpdmUgQ2FyZSBNZWRpY2luZSIpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgc3BlY2lhbHR5X25hbWUpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9wZXJjX29jYyA9IG1lYW4ocGVyY2VudGFnZV9vY2N1cGFuY3kpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBtZWFuX3BlcmNfb2NjKSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gc3BlY2lhbHR5X25hbWUsIGdyb3VwID0gc3BlY2lhbHR5X25hbWUpKSsNCiAgZ2VvbV9wb2ludCgpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KICANCiAgDQogIA0KYGBgDQoNCg0KDQpgYGB7cn0NCmFfZV9iZWRzICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlcikgJT4lIA0KICBzdW1tYXJpc2UobWVhbl9hdmFpbGFibGVfYmVkcyA9IG1lYW4oYXZlcmFnZV9hdmFpbGFibGVfc3RhZmZlZF9iZWRzLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBtZWFuX2F2YWlsYWJsZV9iZWRzKSkrDQogIGdlb21fbGluZShncm91cCA9IjEiKSsNCiAgZ2VvbV9wb2ludCgpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1KSkNCmBgYA0KDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCmBgYHtyfQ0KYWdlX3NleCA8LSByZWFkX2NzdigicmF3X2RhdGEvbm9uX2NvdmlkX3Jhd19kYXRhL2lucGF0aWVudF9hbmRfZGF5Y2FzZV9ieV9uaHNfYm9hcmRfb2ZfdHJlYXRtZW50X2FnZV9hbmRfc2V4LmNzdiIpICU+JSBqYW5pdG9yOjpjbGVhbl9uYW1lcygpDQoNCmhlYWx0aF9ib2FyZF9uYW1lcyA8LSByZWFkX2NzdigicmF3X2RhdGEvbm9uX2NvdmlkX3Jhd19kYXRhL2hlYWx0aF9ib2FyZF9uYW1lcy5jc3YiKQ0KDQphZ2Vfc2V4ICU+JSANCiAgY291bnQoaGIpDQoNCnNlYXNvbl9hZ2Vfc2V4IDwtIGFnZV9zZXggJT4lIA0KICBtdXRhdGUoZGF0ZSA9IHlxKHF1YXJ0ZXIpLA0KICAgICAgICAgeWVhciA9IHllYXIoZGF0ZSksDQogICAgICAgICBtb250aCA9IG1vbnRoKGRhdGUsIGxhYmVsID0gVFJVRSwgYWJiciA9IEZBTFNFKSwNCiAgICAgICAgIHNlYXNvbiA9IGNhc2Vfd2hlbigNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIkRlY2VtYmVyIikgfiAiV2ludGVyIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIkphbnVhcnkiKSB+ICJXaW50ZXIiLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiRmVicnVhcnkiKSB+ICJXaW50ZXIiLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiTWFyY2giKSB+ICJTcHJpbmciLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiQXByaWwiKSB+ICJTcHJpbmciLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiTWF5IikgfiAiU3ByaW5nIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIkp1bmUiKSB+ICJTdW1tZXIiLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiSnVseSIpIH4gIlN1bW1lciIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJBdWd1c3QiKSB+ICJTdW1tZXIiLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiU2VwdGVtYmVyIikgfiAiQXV0dW1uIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIk9jdG9iZXIiKSB+ICJBdXR1bW4iLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiTm92ZW1iZXIiKSB+ICJBdXR1bW4iKSwNCiAgICAgICAgIHNlYXNvbiA9IGZhY3RvcihzZWFzb24sIG9yZGVyID0gVFJVRSkpIA0KYGBgDQpgYGB7cn0NCg0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KHpvbykNCg0KIyBjaGFuZ2UgcXVhcnRlciBjb2x1bW4gaW50byB0aGUgZGF0ZSBhdCB0aGUgc3RhcnQgb2YgZWFjaCBxdWFydGVyDQogYWdlX3NleCA8LSAgYWdlX3NleCAlPiUgDQogICAgbXV0YXRlKHF1YXJ0ZXIgPSB5cShxdWFydGVyKSkNCg0KICMgc2hvd3MgdGhlIHRvdGFsIGxlbmd0aCBvZiBzdGF5IGJ5IGFnZSBicmFja2V0IGZvciBlbWVyZ2VuY3kgaW5wYXRpZW50cw0KYWdlX3NleCAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRW1lcmdlbmN5IElucGF0aWVudHMiKSAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIGFnZSkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfbGVuZ3RoX29mX3N0YXkgPSBzdW0obGVuZ3RoX29mX3N0YXkpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSB0b3RhbF9sZW5ndGhfb2Zfc3RheSkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IGFnZSkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1KSkNCg0KDQpgYGANCg0KDQoNCg0KDQpgYGB7cn0NCmFnZV9zZXggJT4lIA0KY291bnQoYWRtaXNzaW9uX3R5cGUpDQoNCmFnZV9zZXgNCmBgYA0KDQpgYGB7cn0NCiAjIHNob3dzIHRoZSB0b3RhbCBsZW5ndGggb2Ygc3RheSBieSBhZ2UgYnJhY2tldCBmb3IgZWxlY3RpdmUgaW5wYXRpZW50cw0KYWdlX3NleCAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRWxlY3RpdmUgSW5wYXRpZW50cyIpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgYWdlKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9sZW5ndGhfb2Zfc3RheSA9IHN1bShsZW5ndGhfb2Zfc3RheSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IHRvdGFsX2xlbmd0aF9vZl9zdGF5KSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gYWdlKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKQ0KYGBgDQoNCmBgYHtyfQ0KICMgc2hvd3MgdGhlIG1lYW4gbGVuZ3RoIG9mIHN0YXkgYnkgYWdlIGJyYWNrZXQgZm9yIGVtZXJnZW5jeSBpbnBhdGllbnRzDQojY2FuIGZhY2V0IGJ5IHNleCBhbHNvIGlmIHJlcXVpcmVkDQphZ2Vfc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kgSW5wYXRpZW50cyIpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgYWdlKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfbGVuZ3RoX29mX3N0YXkgPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXksIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2Z19sZW5ndGhfb2Zfc3RheSkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IGFnZSwgZ3JvdXAgPSBhZ2UpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSkpDQogICNmYWNldF93cmFwKCB+IHNleCkNCg0KICMgc2hvd3MgdGhlIG1lYW4gbGVuZ3RoIG9mIHN0YXkgYnkgYWdlIGJyYWNrZXQgZm9yIGVsZWN0aXZlIGlucGF0aWVudHMNCiMgY2FuIGZhY2V0IGJ5IHNleCANCmFnZV9zZXggJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVsZWN0aXZlIElucGF0aWVudHMiKSAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIGFnZSkgJT4lIA0KICBzdW1tYXJpc2UoYXZnX2xlbmd0aF9vZl9zdGF5ID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9zdGF5LCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBhdmdfbGVuZ3RoX29mX3N0YXkpKSsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBhZ2UsIGdyb3VwID0gYWdlKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKQ0KIyAgICNmYWNldF93cmFwKH4gc2V4KQ0KYGBgDQoNCmBgYHtyfQ0KYWdlX3NleCAlPiUgDQogIG11dGF0ZShkYXRlID0geXEocXVhcnRlciksDQogICAgICAgICB5ZWFyID0geWVhcihkYXRlKSwNCiAgICAgICAgIG1vbnRoID0gbW9udGgoZGF0ZSwgbGFiZWwgPSBUUlVFLCBhYmJyID0gRkFMU0UpLA0KICAgICAgICAgc2Vhc29uID0gY2FzZV93aGVuKA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiRGVjZW1iZXIiKSB+ICJXaW50ZXIiLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiSmFudWFyeSIpIH4gIldpbnRlciIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJGZWJydWFyeSIpIH4gIldpbnRlciIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJNYXJjaCIpIH4gIlNwcmluZyIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJBcHJpbCIpIH4gIlNwcmluZyIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJNYXkiKSB+ICJTcHJpbmciLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiSnVuZSIpIH4gIlN1bW1lciIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJKdWx5IikgfiAiU3VtbWVyIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIkF1Z3VzdCIpIH4gIlN1bW1lciIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJTZXB0ZW1iZXIiKSB+ICJBdXR1bW4iLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiT2N0b2JlciIpIH4gIkF1dHVtbiIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJOb3ZlbWJlciIpIH4gIkF1dHVtbiIpLA0KICAgICAgICAgc2Vhc29uID0gZmFjdG9yKHNlYXNvbiwgb3JkZXIgPSBUUlVFKSkgDQpgYGANCg0KDQpgYGB7cn0NCg0KYWdlX3NleCAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRW1lcmdlbmN5IElucGF0aWVudHMiKSAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIHNleCkgJT4lIA0KICBzdW1tYXJpc2UoYXZnX2xlbmd0aF9vZl9zdGF5ID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9zdGF5LCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBhdmdfbGVuZ3RoX29mX3N0YXkpKSsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBzZXgsIGdyb3VwID0gc2V4KSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKSsNCiAgZ2VvbV9zbW9vdGgoYWVzKGNvbG91ciA9IHNleCwgZ3JvdXAgPSBzZXgpLCBzZSA9IEZBTFNFKSsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gc2V4KSwgc2l6ZSA9IDAuNSkrDQogIGxhYnModGl0bGUgPSAiRW1lcmdlbmN5IElucGF0aWVudCBieSBnZW5kZXIgYW5kIGF2ZXJhZ2UgbGVuZ3RoIG9mIHN0YXkiKQ0KDQoNCmFnZV9zZXggJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVsZWN0aXZlIElucGF0aWVudHMiKSAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIHNleCkgJT4lIA0KICBzdW1tYXJpc2UoYXZnX2xlbmd0aF9vZl9zdGF5ID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9zdGF5LCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBhdmdfbGVuZ3RoX29mX3N0YXkpKSsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBzZXgsIGdyb3VwID0gc2V4KSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKSsNCiAgZ2VvbV9zbW9vdGgoYWVzKGNvbG91ciA9IHNleCwgZ3JvdXAgPSBzZXgpLCBzZSA9IEZBTFNFKSsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gc2V4KSwgc2l6ZSA9IDAuNSkrDQogIGxhYnModGl0bGUgPSAiRWxlY3RpdmUgSW5wYXRpZW50IGJ5IGdlbmRlciBhbmQgYXZlcmFnZSBsZW5ndGggb2Ygc3RheSIpDQoNCmBgYA0KDQoNCmBgYHtyfQ0KIyBlbWVyZ2VuY3kgaW5wYXRpZW50IGJ5IGFnZSBhbmQgYXZnIGxlbmd0aCBvZiBzdGF5DQphZ2Vfc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kgSW5wYXRpZW50cyIpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgYWdlKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfbGVuZ3RoX29mX3N0YXkgPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXksIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2Z19sZW5ndGhfb2Zfc3RheSkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IGFnZSwgZ3JvdXAgPSBhZ2UpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSkpKw0KICAjZ2VvbV9zbW9vdGgoYWVzKGNvbG91ciA9IHNleCwgZ3JvdXAgPSBzZXgpLCBzZSA9IEZBTFNFKSsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gYWdlKSwgc2l6ZSA9IDAuNSkrDQogIGxhYnModGl0bGUgPSAiRW1lcmdlbmN5IGlucGF0aWVudCBieSBhZ2UgYW5kIGF2ZyBsZW5ndGggb2Ygc3RheSIpDQoNCiMgZWxlY3RpdmUgaW5wYXRpZW50IGJ5IGFnZSBhbmQgYXZnIGxlbmd0aCBvZiBzdGF5DQphZ2Vfc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbGVjdGl2ZSBJbnBhdGllbnRzIikgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBhZ2UpICU+JSANCiAgc3VtbWFyaXNlKGF2Z19sZW5ndGhfb2Zfc3RheSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2Zfc3RheSwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gYXZnX2xlbmd0aF9vZl9zdGF5KSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gYWdlLCBncm91cCA9IGFnZSkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1KSkrDQogICNnZW9tX3Ntb290aChhZXMoY29sb3VyID0gc2V4LCBncm91cCA9IHNleCksIHNlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBhZ2UpLCBzaXplID0gMC41KSsNCiAgbGFicyh0aXRsZSA9ICJFbGVjdGl2ZSBpbnBhdGllbnQgYnkgYWdlIGFuZCBhdmcgbGVuZ3RoIG9mIHN0YXkiKQ0KYGBgDQpgYGB7cn0NCiMgZW1lcmdlbmN5IGlucGF0aWVudCBieSBhZ2UgYW5kIGF2ZyBlcGlzb2Rlcw0KYWdlX3NleCAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRW1lcmdlbmN5IElucGF0aWVudHMiKSAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIGFnZSkgJT4lIA0KICBzdW1tYXJpc2UoYXZnX2VwaXNvZGVzID0gbWVhbihlcGlzb2RlcywgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gYXZnX2VwaXNvZGVzKSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gYWdlLCBncm91cCA9IGFnZSkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1KSkrDQogICNnZW9tX3Ntb290aChhZXMoY29sb3VyID0gc2V4LCBncm91cCA9IHNleCksIHNlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBhZ2UpLCBzaXplID0gMC41KSsNCiAgbGFicyh0aXRsZSA9ICJFbWVyZ2VuY3kgaW5wYXRpZW50IGJ5IGFnZSBhbmQgYXZnIGVwaXNvZGVzIikNCg0KIyBlbWVyZ2VuY3kgaW5wYXRpZW50IGJ5IGFnZSBhbmQgYXZnIGVwaXNvZGVzDQphZ2Vfc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbGVjdGl2ZSBJbnBhdGllbnRzIikgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBhZ2UpICU+JSANCiAgc3VtbWFyaXNlKGF2Z19lcGlzb2RlcyA9IG1lYW4oZXBpc29kZXMsIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2Z19lcGlzb2RlcykpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IGFnZSwgZ3JvdXAgPSBhZ2UpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSkpKw0KICAjZ2VvbV9zbW9vdGgoYWVzKGNvbG91ciA9IHNleCwgZ3JvdXAgPSBzZXgpLCBzZSA9IEZBTFNFKSsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gYWdlKSwgc2l6ZSA9IDAuNSkrDQogIGxhYnModGl0bGUgPSAiRW1lcmdlbmN5IGlucGF0aWVudCBieSBhZ2UgYW5kIGF2ZyBlcGlzb2RlcyIpDQpgYGANCg0KDQoNCmBgYHtyfQ0KIyBQbG90IGNvbXBhcmlzb24gb2YgRW1lcmdlbmN5IHZzIEVsZWN0aXZlIHN1Ym1pc3Npb25zDQphZ2Vfc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlICVpbiUgYygiRW1lcmdlbmN5IElucGF0aWVudHMiLCAiRWxlY3RpdmUgSW5wYXRpZW50cyIpKSAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIGFkbWlzc2lvbl90eXBlKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfc3RheSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2Zfc3RheSwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gYXZnX3N0YXksIGNvbG91ciA9IGFkbWlzc2lvbl90eXBlKSkrDQogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBhZG1pc3Npb25fdHlwZSkpKw0KICBnZW9tX3BvaW50KCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQoNCmBgYA0KDQoNCmBgYHtyfQ0KIyBhdmdfc3RheSBieSBhZG1pc3Npb24gdHlwZQ0KYWdlX3NleCAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIGFkbWlzc2lvbl90eXBlKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfc3RheSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2Zfc3RheSwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gYXZnX3N0YXksIGNvbG91ciA9IGFkbWlzc2lvbl90eXBlKSkrDQogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBhZG1pc3Npb25fdHlwZSkpKw0KICBnZW9tX3BvaW50KCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQoNCg0KIyBhdmdfc3RheSBmb3IgYWxsIHR5cGVzDQphZ2Vfc2V4ICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlcikgJT4lIA0KICBzdW1tYXJpc2UoYXZnX3N0YXkgPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXksIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2Z19zdGF5LCBncm91cCA9IDEpKSsNCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IDEpKSsNCiAgZ2VvbV9wb2ludCgpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KDQojIG51bWJlciBvZiBzdGF5cyBmb3IgYWxsIHR5cGVzDQphZ2Vfc2V4ICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlcikgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfc3RheXMgPSBzdW0oc3RheXMsIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IHRvdGFsX3N0YXlzLCBncm91cCA9IDEpKSsNCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IDEpKSsNCiAgZ2VvbV9wb2ludCgpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KYGBge3J9DQpzaW1kIDwtIHJlYWRfY3N2KCJyYXdfZGF0YS9ub25fY292aWRfcmF3X2RhdGEvaW5wYXRpZW50X2FuZF9kYXljYXNlX2J5X25oc19ib2FyZF9vZl90cmVhdG1lbnRfYW5kX3NpbWQuY3N2IikgJT4lIGphbml0b3I6OmNsZWFuX25hbWVzKCkNCmBgYA0KYGBge3J9DQojdG90YWwgZXBpc29kZXMoaG9zcGl0YWxpc2F0aW9ucz8pIGJ5IHNpbWQgdmFsdWUNCnNpbWQgJT4lIA0KICBkcm9wX25hKHNpbWQpICU+JQ0KICBtdXRhdGUoc2ltZCA9IGFzLmZhY3RvcihzaW1kKSkgJT4lICMgZ2l2ZXMgZWFjaCBzaW1kIGEgc2VwYXJhdGUgY29sb3VyDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIHNpbWQpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2VwaXNvZGVzID0gc3VtKGVwaXNvZGVzLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSB0b3RhbF9lcGlzb2RlcywgZ3JvdXAgPSBzaW1kKSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gc2ltZCkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6Y29tbWEpDQogIA0KI2F2ZyBlcGlzb2Rlcyhob3NwaXRhbGlzYXRpb25zPykgYnkgc2ltZCB2YWx1ZQ0Kc2ltZCAlPiUgDQogIGRyb3BfbmEoc2ltZCkgJT4lDQogIG11dGF0ZShzaW1kID0gYXMuZmFjdG9yKHNpbWQpKSAlPiUgIyBnaXZlcyBlYWNoIHNpbWQgYSBzZXBhcmF0ZSBjb2xvdXINCiAgZ3JvdXBfYnkocXVhcnRlciwgc2ltZCkgJT4lIA0KICBzdW1tYXJpc2UoYXZnX2VwaXNvZGVzID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9lcGlzb2RlLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBhdmdfZXBpc29kZXMsIGdyb3VwID0gc2ltZCkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IHNpbWQpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkrDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmNvbW1hKQ0KICANCmBgYA0KDQoNCmBgYHtyfQ0KIyBwbG90IGF2ZyBzdGF5IGxlbmd0aCBmb3IgbW9zdCBhbmQgbGVhc3QgZGVwcml2ZWQgZm9yIGVtZXJnZW5jeSB1bnBhdGllbnRzDQpzaW1kICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kgSW5wYXRpZW50cyIsIHNpbWQgJWluJSBjKDEsNSkpICU+JSANCiAgZHJvcF9uYShzaW1kKSAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsc2ltZCkgJT4lIA0KICBzdW1tYXJpc2UoYXZnX3N0YXlfbGVuZ3RoID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9zdGF5LCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBhdmdfc3RheV9sZW5ndGgpKSArDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gc2ltZCwgZ3JvdXAgPSBzaW1kKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQogIA0KYGBgDQoNCg0KYGBge3J9DQpzcGVjaWFsaXR5IDwtIHJlYWRfY3N2KCJyYXdfZGF0YS9ub25fY292aWRfcmF3X2RhdGEvaW5wYXRpZW50X2FuZF9kYXljYXNlX2J5X25oc19ib2FyZF9vZl90cmVhdG1lbnRfYW5kX3NwZWNpYWx0eS5jc3YiKSAlPiUgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKQ0KYGBgDQoNCmBgYHtyfQ0Kc3BlY2lhbGl0eSAlPiUgDQogIGNvdW50KGFkbWlzc2lvbl90eXBlKQ0KDQpzcGVjaWFsaXR5ICU+JSANCiAgY291bnQoaGIpDQoNCnNwZWNpYWxpdHkgJT4lIA0KICBjb3VudChsb2NhdGlvbikNCg0Kc3BlY2lhbGl0eSAlPiUgDQogIGNvdW50KHNwZWNpYWx0eV9uYW1lKQ0KDQojIGFkZCBhdmVyYWdlcyANCnNwZWNpYWxpdHlfYXZlcmFnZXMgPC0gc3BlY2lhbGl0eSAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIGFkbWlzc2lvbl90eXBlKSAlPiUgDQogIG11dGF0ZShhdmdfbGVuZ3RoX3NwZWxsPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX3NwZWxsLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgYXZnX2xlbmd0aF9lcGlzb2RlID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9lcGlzb2RlLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIHVuZ3JvdXAoKQ0KDQoNCnNwZWNpYWxpdHlfYXZlcmFnZXMgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBhZG1pc3Npb25fdHlwZSkgJT4lIA0KICBzbGljZSgxKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBhdmVyYWdlX2xlbmd0aF9vZl9lcGlzb2RlLCBncm91cCA9IGFkbWlzc2lvbl90eXBlKSkgKyANCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBhZG1pc3Npb25fdHlwZSkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KDQpgYGANCg0KYGBge3J9DQphZV93YWl0X3RpbWVzIDwtIHJlYWRfY3N2KCJyYXdfZGF0YS9ub25fY292aWRfcmF3X2RhdGEvbW9udGhseV9hZV93YWl0aW5ndGltZXNfMjAyMjA2LmNzdiIpICU+JSBqYW5pdG9yOjpjbGVhbl9uYW1lcygpDQoNCiNnbGltcHNlKGFlX3dhaXRfdGltZXMpDQoNCg0KI21ha2UgYSBkYXRlIGFuZCB5ZWFyIGNvbHVtbiB3aXRoIHRoZSBmaXJzdCBkYXRlIG9mIGV2ZXJ5IG1vbnRoDQphZV93YWl0X3RpbWVzIDwtIGFlX3dhaXRfdGltZXMgJT4lIA0KICBtdXRhdGUoZGF0ZSA9IHltKG1vbnRoKSwgLmFmdGVyID0gbW9udGgsDQogICAgICAgICB5ZWFyID0geWVhcihkYXRlKSkNCg0KI21ha2UgYSBwZXJjZW50IGNvbHVtbiB3aXRoIHBlcmNlbnQgb2YgcGF0aWVudHMgbWVldGluZyB0aGUgNGhyIHRhcmdldCB0aW1lDQphZV93YWl0X3RpbWVzIDwtIGFlX3dhaXRfdGltZXMgJT4lIA0KICBtdXRhdGUocGVyY2VudF80aHJfdGFyZ2V0X2FjaGlldmVkID0gKG51bWJlcl9tZWV0aW5nX3RhcmdldF9hZ2dyZWdhdGUvbnVtYmVyX29mX2F0dGVuZGFuY2VzX2FnZ3JlZ2F0ZSkqMTAwKSAlPiUgDQogICNhZGQgYW4gOGhyIG9uZSAtIG5vdCBjdXJyZW50bHkgdXNlZA0KbXV0YXRlKHBlcmNlbnRfc2Vlbl93aXRoaW5fOGhyID0gKChudW1iZXJfb2ZfYXR0ZW5kYW5jZXNfYWdncmVnYXRlLWF0dGVuZGFuY2VfZ3JlYXRlcjhocnMpL251bWJlcl9vZl9hdHRlbmRhbmNlc19hZ2dyZWdhdGUpKjEwMCkNCmBgYA0KDQoNCmBgYHtyfQ0KIyBkcmF3IHBlcmNlbnRhZ2Ugb2YgNCBob3VyIHdhaXQgZm9yIGFsbCB5ZWFycw0KZm9yX3Bsb3RseSA8LSBhZV93YWl0X3RpbWVzICU+JSANCiAgZmlsdGVyKGRlcGFydG1lbnRfdHlwZSA9PSAiRW1lcmdlbmN5IERlcGFydG1lbnQiKSAlPiUgDQogIGdyb3VwX2J5KGRhdGUsIGRlcGFydG1lbnRfdHlwZSkgJT4lIA0KICBzdW1tYXJpc2UoYXZnXzRocl90YXJnZXRfbWFkZSA9IG1lYW4ocGVyY2VudF80aHJfdGFyZ2V0X2FjaGlldmVkKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gYXZnXzRocl90YXJnZXRfbWFkZSkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IGRlcGFydG1lbnRfdHlwZSkpKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiNiBtb250aHMiLCBkYXRlX2xhYmVscyA9ICAiJWIgJVkiKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxLCBzaXplID03KSkrDQogIGdlb21fc21vb3RoKCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAwOC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAwOS0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMS0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMi0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMy0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNS0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNi0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNy0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxOC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxOS0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAyMC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGxhYnModGl0bGUgPSAicGVyY2VudGFnZSBvZiBBJkUgZGVwYXJ0bWVudHMgbWVldGluZyB0aGUgNCBociB0YXJnZXQgdHVybmFyb3VuZCBmb3IgcGF0aWVudHMiLA0KICAgICAgIHN1YnRpdGxlID0gImFkZGVkIGluIHZlcnRpY2FsIGxpbmVzIGZvciBKYW51YXJ5IHRvIGhlbHAiKQ0KDQpnZ3Bsb3RseShmb3JfcGxvdGx5KQ0KYGBgDQoNCmBgYHtyfQ0KIyA0aHIgd2FpdCBieSBoZWFsdGggYm9hcmQgZm9yIGFsbCB5ZWFycyBmYWNldCB3cmFwcGVkDQphZV93YWl0X3RpbWVzICU+JSANCiAgZmlsdGVyKGRlcGFydG1lbnRfdHlwZSA9PSAiRW1lcmdlbmN5IERlcGFydG1lbnQiKSAlPiUgDQogIGdyb3VwX2J5KGRhdGUsIGhidCkgJT4lIA0KICBtdXRhdGUoYXZnXzRocl90YXJnZXRfbWFkZSA9IG1lYW4ocGVyY2VudF80aHJfdGFyZ2V0X2FjaGlldmVkKSkgJT4lIA0KICBzbGljZSgxKSAlPiUgIA0KICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gYXZnXzRocl90YXJnZXRfbWFkZSkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IGhidCkpKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiNiBtb250aHMiLCBkYXRlX2xhYmVscyA9ICAiJWIgJVkiKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxLCBzaXplID03KSkrDQogIGdlb21fc21vb3RoKCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAwOC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAwOS0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMS0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMi0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxMy0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNS0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNi0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNy0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxOC0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxOS0wMS0wMSIpKSwgbGluZXR5cGU9NCkrDQogIGZhY2V0X3dyYXAofiBoYnQpDQpgYGANCg0KYGBge3J9DQp0YXJnZXRfMjAwNyA8LSBhZV93YWl0X3RpbWVzICU+JQ0KICBncm91cF9ieSh5ZWFyLCBoYnQpICU+JSANCiAgc3VtbWFyaXNlKGFlXzRocl90YXJnZXRfYWNoaWV2ZWQgPSBtZWFuKHBlcmNlbnRfNGhyX3RhcmdldF9hY2hpZXZlZCwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBmaWx0ZXIoeWVhciA9PSAyMDA3KSAlPiUgDQogIHJlbmFtZShhZV90YXJnZXRfMjAwNyA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgc2VsZWN0KGhidCxhZV90YXJnZXRfMjAwNykNCg0KdGFyZ2V0XzIwMTggPC0gYWVfd2FpdF90aW1lcyAlPiUNCiAgZ3JvdXBfYnkoeWVhciwgaGJ0KSAlPiUgDQogIHN1bW1hcmlzZShhZV80aHJfdGFyZ2V0X2FjaGlldmVkID0gbWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQsIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZmlsdGVyKHllYXIgPT0gMjAxOCkgJT4lIA0KICByZW5hbWUoYWVfdGFyZ2V0XzIwMTggPSBhZV80aHJfdGFyZ2V0X2FjaGlldmVkKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIHNlbGVjdChoYnQsYWVfdGFyZ2V0XzIwMTgpDQoNCmBgYA0KDQoNCg0KDQoNCg0KYGBge3J9DQpsaWJyYXJ5KHNmKQ0KDQpzY290bGFuZCA8LSBzdF9yZWFkKCIuLi9TR19OSFNfSGVhbHRoQm9hcmRzXzIwMTlfc2hhcGVmaWxlL1NHX05IU19IZWFsdGhCb2FyZHNfMjAxOS5zaHAiKQ0KDQojIHZpZXcoc2NvdGxhbmQpDQojIA0KaGVhZChzY290bGFuZCwgMykNCiMgDQpwbG90KHNjb3RsYW5kWy0xXSkNCg0Kc2NvdGxhbmQgPC0gIHNjb3RsYW5kICU+JSANCiAgbXV0YXRlKGNlbnRyZXMgPSBzdF9jZW50cm9pZChzdF9tYWtlX3ZhbGlkKGdlb21ldHJ5KSkpICU+JQ0KICAgIG11dGF0ZShsYXQgPSBzdF9jb29yZGluYXRlcyhjZW50cmVzKVssMV0sDQogICAgICAgICAgIGxvbmcgPSBzdF9jb29yZGluYXRlcyhjZW50cmVzKVssMl0sDQogICAgICAgICAgIHRhcmdldF8yMDA3ID0gdGFyZ2V0XzIwMDckYWVfdGFyZ2V0XzIwMDcsDQogICAgICAgICAgIHRhcmdldF8yMDE4ID0gdGFyZ2V0XzIwMTgkYWVfdGFyZ2V0XzIwMTgsDQogICAgICAgICAgIGNoYW5nZV9hZSA9IHRhcmdldF8yMDA3IC0gdGFyZ2V0XzIwMTgpDQoNCmdncGxvdChkYXRhID0gc2NvdGxhbmQpICsNCiAgICBnZW9tX3NmKGFlcyhmaWxsID0gY2hhbmdlX2FlKSkgKw0KICAgIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG9wdGlvbiA9ICJwbGFzbWEiKSsNCiAgbGFicyh0aXRsZSA9ICJwZXJjZW50IGNoYW5nZSBpbiBBJkUgZGVwdHMgbWVldGluZyB0aGUgNCBob3VyIHRhcmdldCAyMDA3IC0gMjAxOCIpDQogIA0KDQpnZ3Bsb3QoZGF0YSA9IHNjb3RsYW5kKSArDQogICAgZ2VvbV9zZihhZXMoZmlsbCA9IHRhcmdldF8yMDE4KSkgKw0KICAgIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG9wdGlvbiA9ICJwbGFzbWEiKSsNCiAgbGFicyh0aXRsZSA9ICJQZXJjZW50IG9mIEEmRSBkZXB0cyBtYWtpbmcgdGhlIDRociB0YXJnZXQiKQ0KYGBgDQoNCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IHNjb3RsYW5kKSArDQpnZW9tX3NmKGZpbGwgPSAiZ3JlZW4iKSsNCmdncmVwZWw6Omdlb21fdGV4dF9yZXBlbChhZXMoeCA9IGxhdCAsIHkgPSBsb25nLCBsYWJlbCA9IHBhc3RlKEhCQ29kZSwgSEJOYW1lLCBzZXAgPSAiXG4iKSksIG1pbi5zZWdtZW50Lmxlbmd0aCA9IDAuMDUsc2l6ZSA9IDMsIGNvbG9yID0gImJsYWNrIiwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgdGhlbWVfdm9pZCgpDQpgYGANCg0KDQpgYGB7cn0NCg0KbGlicmFyeShzZikNCg0Kc2NvdGxhbmRfc21hbGxlciA8LSBzY290bGFuZCAlPiUgIyBtYWtlIGEgc21hbGxlciB2ZXJzaW9uIGZvciBwZXJmb3JtYW5jZSBpc3N1ZXMNCiAgc3Rfc2ltcGxpZnkoVFJVRSwgZFRvbGVyYW5jZSA9IDIwMDApDQojZml4ZXMgcHJvYmxlbXMgY2F1c2VkIGJ5IGFib3ZlIA0Kc2NvdGxhbmRfc21hbGxlciA8LSBzZjo6c3RfY2FzdChzY290bGFuZF9zbWFsbGVyLCAiTVVMVElQT0xZR09OIikNCg0KDQojIA0KIyAgIGZpZyA8LSBnZ3Bsb3RseSgNCiMgICAgIGdncGxvdChzY290bGFuZCkrDQojICAgZ2VvbV9zZihhZXMoZmlsbCA9IEhCTmFtZSkpDQojICkNCiMgICBmaWcNCg0KICANCiAgcCA8LSBnZ3Bsb3Qoc2NvdGxhbmRfc21hbGxlcikgKyANCiAgZ2VvbV9zZihhZXMoZmlsbCA9IEhCTmFtZSwgdGV4dCA9IHBhc3RlKCI8Yj4iLCBIQk5hbWUsICI8L2I+XG4iLCBIQkNvZGUpKSkrDQogICAgdGhlbWVfdm9pZCgpDQogIHAgJT4lDQogIGdncGxvdGx5KHRvb2x0aXAgPSAidGV4dCIpICU+JQ0KICBzdHlsZShob3ZlcmxhYmVsID0gbGlzdChiZ2NvbG9yID0gIndoaXRlIiksIGhvdmVyb24gPSAiZmlsbCIpDQogICAgDQogIA0KYGBgDQoNCmBgYHtyfQ0KY292aWRfYWdlX3NleCA8LSByZWFkX2NzdigicmF3X2RhdGEvY292aWRfcmF3X2RhdGEvaG9zcGl0YWxfYWRtaXNzaW9uc19oYl9hZ2VzZXhfMjAyMjAzMDIuY3N2IikNCg0KaGVhZChjb3ZpZF9hZ2Vfc2V4KQ0KYGBgDQoNCg==